#!/usr/bin/env python
#-*- coding:utf-8 -*-

# taggen.py
#
# Copyright (c) 2007 Marcelo Lira dos Santos
#
# Author: Marcelo Lira dos Santos <setanta@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade
import random
import os
from os.path import join
from os.path import isdir
from os.path import isfile
import shutil

import core
import data
import store
import guisupport as gs
from item_window import ItemWindow
from places_dialog import PlacesDialog
from persona_dialog import PersonaDialog
from attribute_wheel import AttributeWheel
from combat_viewport import CombatViewport
from value_bar import ValueBar
from persona_sizer import PersonaSizer
from persona_age import PersonaAge
try:
    import config as cfg
except:
    import config_dev as cfg

class AppWindow:

    def __init__(self):
        self.persona_orig = None
        self.persona = None
        self.store = store.Store()
        self.tmp_persona_names = None
        self.editing_skill_spec_id = -1

        wtree = gtk.glade.XML(join(cfg.DATAPATH, 'taggen.glade'))

        self.window = wtree.get_widget('main_window')
        self.window.set_icon(cfg.APPICON)
        self.window.connect('destroy', self.__exit)

        #self.statusbar = wtree.get_widget('statusbar')

        #gtk.rc_parse(join(cfg.DATAPATH, 'taggen.rc'))

        self.item_window = ItemWindow(wtree, self.store)
        self.persona_dialog = PersonaDialog(wtree, self.store)
        self.about_dialog = wtree.get_widget('about_dialog')
        logo = gtk.gdk.pixbuf_new_from_file(join(cfg.PIXMAPSPATH,
                                                 'tagmar_logo.png'))
        self.about_dialog.set_property('logo', logo)
        self.about_dialog.set_property('name', 'TagGen')
        self.about_dialog.set_icon(cfg.APPICON)

        self.places_dialog = PlacesDialog(wtree, self.store)

        self.persona_sizer = PersonaSizer(wtree)
        self.persona_age = PersonaAge(wtree, self.store)

        self.hbox_magic = wtree.get_widget('hbox_magic')

        # Specialization dialog
        self.spec_dialog = wtree.get_widget('specialization_dialog')
        self.spec_dialog.set_icon(cfg.APPICON)
        self.spec_dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                     gtk.STOCK_OK, gtk.RESPONSE_OK)
        self.spec_skill_label = wtree.get_widget('spec_skill_label')

        self.spec_comboentry = wtree.get_widget('spec_comboentry')
        self.spec_completion = gtk.EntryCompletion()
        self.spec_combo_model, self.spec_combo_filter = \
                gs.init_specializations(self.spec_comboentry,
                                        self.spec_completion,
                                        self.store)
        self.spec_combo_filter.set_visible_func(
                self.skill_spec_suggestion_visible, data=None)


        # Image Chooser dialog
        self.imagechooser_dialog = wtree.get_widget('imagechooser_dialog')
        self.imagechooser_dialog.set_icon(cfg.APPICON)
        self.preview = gs.init_image_dialog(self.imagechooser_dialog)

        # Character collection
        self.persona_collection = wtree.get_widget('persona_collection')
        self.persona_collection_model = \
                gs.init_personas(self.persona_collection, self.store)

        # Various entries
        self.player_entry = wtree.get_widget('player_entry')
        self.player_entry_completion = gtk.EntryCompletion()
        self.player_entry_completion_model = \
            gs.init_players_names(self.player_entry_completion,
                                  self.store.get_players_names())
        self.player_entry.set_completion(self.player_entry_completion)

        self.name_entry = wtree.get_widget('name_entry')
        self.name_entry_completion = gtk.EntryCompletion()
        self.name_entry_completion_model_filter = \
                self.persona_collection_model.filter_new()
        self.name_entry_completion_model_filter.set_visible_func(
                self.personas_names_visible, data=None)
        self.name_entry_completion.set_model(
                self.name_entry_completion_model_filter)
        self.name_entry_completion.set_text_column(gs.PERSONA_COL_NAME)
        self.name_entry.set_completion(self.name_entry_completion)

        self.race_entry = wtree.get_widget('race_entry')
        self.profession_entry = wtree.get_widget('profession_entry')
        self.prof_spec_label = wtree.get_widget('prof_spec_label')
        self.prof_spec_entry = wtree.get_widget('prof_spec_entry')

        self.xp_spin = wtree.get_widget('xp_spin')
        self.xp_next_entry = wtree.get_widget('xp_next_entry')
        self.level_entry = wtree.get_widget('level_entry')

        self.social_entry = wtree.get_widget('social_entry')
        self.god_combo = wtree.get_widget('god_combo')
        self.god_combo_model = \
            gs.init_gods(self.god_combo, self.store.get_gods_list())

        self.avatar_image = wtree.get_widget('avatar_image')

        self.rf_label = wtree.get_widget('rf_label')
        self.rm_label = wtree.get_widget('rm_label')
        self.speed_label= wtree.get_widget('speed_label')
        self.karma_label = wtree.get_widget('karma_label')
        self.eh_label = wtree.get_widget('eh_label')
        self.ef_label = wtree.get_widget('ef_label')
        self.defense_label = wtree.get_widget('defense_label')
        self.passive_defense_label = wtree.get_widget('passive_defense_label')
        self.absorption_label = wtree.get_widget('absorption_label')

        gs.init_images(wtree)

        self.show_skills_button = wtree.get_widget('show_skills_button')
        self.show_spells_button = wtree.get_widget('show_spells_button')
        self.show_equip_button = wtree.get_widget('show_equip_button')

        notebook = wtree.get_widget('notebook')

        # Attribute Wheel
        self.attribute_wheel = AttributeWheel()
        self.attribute_wheel.connect('value-changed', self.on_attribute_changed)
        self.attributes_viewport = wtree.get_widget('attributes_viewport')
        self.attributes_viewport.add(self.attribute_wheel)

        sec_attr_viewport = wtree.get_widget('sec_attr_viewport')
        sec_attr_viewport.modify_bg(gtk.STATE_NORMAL,
                                    gtk.gdk.color_parse('#FFF'))

        # Progress bars
        self.skill_pts_bar, self.combat_pts_bar, self.weapon_pts_bar = \
                gs.init_skills_value_bars(wtree.get_widget('skills_pts_table'))
        self.magic_pts_bar = \
                gs.init_magic_value_bar(wtree.get_widget('magic_pts_align'))

        # Learned skills
        self.skills_list = wtree.get_widget('skills_list')
        self.skills_list_model, self.skills_list_filter = \
                gs.init_skills(self.skills_list, self.store)
        self.skills_list_filter.set_visible_func(self.skills_visible,
                                                 data=None)

        # Learned Spells
        self.spells_list = wtree.get_widget('spells_list')
        self.spells_list_model, self.spells_list_filter = \
                gs.init_spells(self.spells_list, self.store)
        self.spells_list_filter.set_visible_func(self.spells_visible,
                                                 data=None)

        # Equipment
        self.equipment_list = wtree.get_widget('equipment_list')
        self.equipment_list_model , self.equipment_list_filter = \
                gs.init_equipment(self.equipment_list, self.store)
        self.equipment_list_filter.set_visible_func(self.equipment_visible,
                                                    data=None)

        # Drag weapons/defenses
        self.equipment_list.drag_source_set(gtk.gdk.BUTTON1_MASK,
                                            [('text/plain',
                                              gtk.TARGET_SAME_APP, 1)],
                                            gtk.gdk.ACTION_COPY)

        self.combat_viewport = CombatViewport(wtree)

        self.equip_menu = wtree.get_widget('equip_menu')
        self.equip_menuitem = wtree.get_widget('equip_menuitem')
        self.unequip_menuitem = wtree.get_widget('unequip_menuitem')

        self.copper_label = wtree.get_widget('copper_label')
        self.silver_label = wtree.get_widget('silver_label')
        self.gold_label = wtree.get_widget('gold_label')

        self.hair_entry = wtree.get_widget('hair_entry')
        self.skin_entry = wtree.get_widget('skin_entry')
        self.eyes_entry = wtree.get_widget('eyes_entry')
        self.age_hscale = wtree.get_widget('age_hscale')
        self.height_vscale = wtree.get_widget('height_vscale')
        self.weight_hscale = wtree.get_widget('weight_hscale')

        # Appearence
        self.appearence_textview = wtree.get_widget('appearence_textview')
        self.appearence_textbuffer = gtk.TextBuffer()
        self.appearence_textview.set_buffer(self.appearence_textbuffer)

        # Homeland
        self.homeland_button = wtree.get_widget('homeland_button')

        # History
        self.history_textview = wtree.get_widget('history_textview')
        self.history_textbuffer = gtk.TextBuffer()
        self.history_textview.set_buffer(self.history_textbuffer)

        # Goals
        self.goals_textview = wtree.get_widget('goals_textview')
        self.goals_textbuffer = gtk.TextBuffer()
        self.goals_textview.set_buffer(self.goals_textbuffer)

        self.on_attribute_changed(self.attribute_wheel, None)
        wtree.signal_autoconnect(self)

        self.window.show_all()


    # Callbacks ---------------------------------------------------------------
    def on_button_new_clicked(self, widget):
        self.__new_persona()

    def on_new_activate(self, widget):
        self.__new_persona()

    def on_open_activate(self, widget):
        self.__open_persona()

    def on_button_open_clicked(self, widget):
        self.__open_persona()

    def on_persona_collection_row_activated(self, treeview, path, column):
        char_iter = self.persona_collection_model.get_iter(path)
        self.__open_persona(char_iter)

    def on_equipment_list_row_activated(self, treeview, path, column):
        if self.equipment_list_filter[path][gs.EQUIP_COL_IS_ITEM]:
            item_id = self.equipment_list_filter[path][gs.EQUIP_COL_ID]
            self.__show_item(item_id)

    def on_equipment_list_button_release_event(self, treeview, event):
        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            path, column, x, y = self.equipment_list.get_path_at_pos(x, y)
            if not self.equipment_list_filter[path][gs.EQUIP_COL_IS_ITEM]:
                return True

            qty = self.equipment_list_filter[path][gs.EQUIP_COL_QTD]

            item_id = self.equipment_list_filter[path][gs.EQUIP_COL_ID]
            item = self.store.get_equipment_item(item_id)

            self.equip_menuitem.hide()
            self.unequip_menuitem.hide()

            if item.is_combat() and qty > 0:
                if self.combat_viewport.has_item(item):
                    self.unequip_menuitem.show()
                else:
                    self.equip_menuitem.show()

            self.equip_menu.popup(None, None, None, event.button, event.time)

            return True

    def on_save_activate(self, widget):
        self.save_persona()

    def on_button_save_clicked(self, widget):
        self.save_persona()

    def on_button_print_clicked(self, widget):
        print 'on_button_print_clicked'

    def on_exit_activated(self, widget):
        self.__exit()

    def on_cut_activate(self, widget):
        print 'on_recortar1_activate'

    def on_copy_activate(self, widget):
        print 'on_copiar1_activate'

    def on_paste_activate(self, widget):
        print 'on_colar1_activate'

    def on_delete_activate(self, widget):
        print 'on_excluir1_activate'

    def on_char_sheet_activate(self, widget):
        print 'on_char_sheet_activate'

    def on_persona_dialog_response(self, dialog, response):
        if response in (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT):
            dialog.hide()
            return

        selected_race = self.persona_dialog.get_selected_race()
        selected_profession = self.persona_dialog.get_selected_profession()
        if selected_race is not None and selected_profession is not None:
            self.new_persona(selected_race, selected_profession)
            dialog.hide()
        else:
            gs.message(dialog, 'Você precisa escolher a raça e a '\
                               'profissão de seu personagem.')

    def on_places_dialog_response(self, dialog, response):
        dialog.hide()
        place = self.places_dialog.get_place()
        if place is not None:
            self.homeland_button.set_label(place.name)

    def on_about_activate(self, widget):
        self.about_dialog.show()

    def on_about_dialog_response(self, widget, response):
        widget.hide()

    def on_about_dialog_destroy_event(self, widget):
        widget.hide()
        return True

    def on_image_button_clicked(self, widget):
        self.imagechooser_dialog.show()

    def on_imagechooser_dialog_update_preview(self, filechooser, data=None):
        filename = filechooser.get_preview_filename()
        if filename is None or isdir(filename):
            filechooser.set_preview_widget_active(False)
            self.avatar_pixbuf = None
            return

        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 128, 128)
        if pixbuf is not None:
            self.preview.set_from_pixbuf(pixbuf)
            filechooser.set_preview_widget_active(True)

    def on_imagechooser_dialog_response(self, filechooser, response):
        if response == gtk.RESPONSE_OK:
            gs.save_image_dir(filechooser.get_current_folder())
            source_file = filechooser.get_filename()
            dest_file = join(cfg.APPDATAPATH, 'persona_%d%s' % \
                             (self.persona.id,
                              os.path.splitext(source_file)[1]))

            if self.persona.avatar_file is not None:
                old_file = join(cfg.APPDATAPATH, self.persona.avatar_file)
                if old_file != dest_file and os.path.isfile(old_file):
                    os.remove(old_file)

            shutil.copyfile(source_file, dest_file)
            self.persona.avatar_file = os.path.basename(dest_file)

            self.refresh_avatar_image(dest_file)

        filechooser.hide()

    def on_imagechooser_dialog_delete_event(self, widget, event):
        self.imagechooser_dialog.hide()
        return True

    def on_remove_skill_button_clicked(self, widget):
        self.add_remove_skill(False)

    def on_add_skill_button_clicked(self, widget):
        self.add_remove_skill(True)

    def on_specialization_dialog_response(self, widget, response):
        self.spec_dialog.hide()

        if response == gtk.RESPONSE_CANCEL:
            return

        filter_iter = self.spec_comboentry.get_active_iter()
        iter = self.spec_combo_filter.convert_iter_to_child_iter(filter_iter)

        spec = self.spec_combo_model[iter][gs.SPECSUGGEST_COL_NAME]
        if spec.strip() == '':
            return

        path, column = self.skills_list.get_cursor()
        filter_iter = self.skills_list_filter.get_iter(path)
        parent_iter = self.skills_list_filter.convert_iter_to_child_iter(filter_iter)

        skill_id = self.skills_list_model[parent_iter][gs.SKILLS_COL_ID]
        cost = self.skills_list_model[parent_iter][gs.SKILLS_COL_COST]
        bonus = self.skills_list_model[parent_iter][gs.SKILLS_COL_BONUS]
        level = 1
        total = level + self.persona.get_attribute_by_short_name(bonus)

        self.skills_list_model.append(parent_iter,
                                      [skill_id, spec, cost, level,
                                       bonus, total, False, True, False,
                                       gs.FG_COLOR, gs.COLOR_WHITE])

        self.persona.skill_points -= cost
        self.skill_pts_bar.set_property('value', self.persona.skill_points)

        self.skills_list.expand_row(path, False)

    def on_remove_spell_button_clicked(self, widget):
        self.add_remove_spell(False)

    def on_add_spell_button_clicked(self, widget):
        self.add_remove_spell(True)

    def on_sell_item_cb(self, widget):
        self.buy_sell_item(False)

    def on_buy_item_cb(self, widget):
        self.buy_sell_item(True)


    def on_attribute_changed(self, widget, data):
        if not self.persona:
            return
        values = map(int.__add__, widget.values, widget.modifiers)
        self.refresh_attributes()
        self.refresh_skills(False)

    def on_show_skills_button_toggled(self, widget):
        self.skills_list_filter.refilter()
        self.skills_list.expand_all()

    def on_show_spells_button_toggled(self, widget):
        self.spells_list_filter.refilter()
        self.spells_list.expand_all()

    def on_show_equip_button_toggled(self, widget):
        self.equipment_list_filter.refilter()
        self.equipment_list.expand_all()

    def on_homeland_button_clicked(self, widget):
        self.__show_places()

    def on_equipment_list_drag_data_get(self, treeview, context,
                                        selection, info, timestamp):
        treeselection = treeview.get_selection()
        model, item_iter = treeselection.get_selected()
        if model[item_iter][gs.EQUIP_COL_QTD] > 0:
            selection.set('text/plain', 8,
                          str(model[item_iter][gs.EQUIP_COL_ID]))

    def __get_selected_item(self):
        path, column = self.equipment_list.get_cursor()
        item_id = self.equipment_list_filter[path][gs.EQUIP_COL_ID]
        return self.store.get_equipment_item(item_id)

    def on_equip_item_activate(self, widget):
        item = self.__get_selected_item()
        if self.combat_viewport.equip_item(item):
            self.persona.equip_item(item)
            self.refresh_attributes()

    def on_unequip_item_activate(self, widget):
        item = self.__get_selected_item()
        if self.combat_viewport.unequip_item(item):
            self.persona.unequip_item(item)
            self.refresh_attributes()

    def on_weapons_viewport_drag_data_received(self, widget, ct, x, y,
                                               selection, info, timestamp):
        item = self.store.get_equipment_item(int(selection.data))
        if self.combat_viewport.equip_item(item):
            self.persona.equip_item(item)
            self.refresh_attributes()

    # Actions -----------------------------------------------------------------
    def __new_persona(self):
        self.persona_dialog.run()

    def __open_persona(self, persona_iter=None):
        if persona_iter is None:
            path, column = self.persona_collection.get_cursor()
            persona_iter = self.persona_collection_model.get_iter(path)
        id = self.persona_collection_model[persona_iter][gs.PERSONA_COL_ID]
        self.load_persona(id)

    def __show_item(self, item_id):
        rect = self.equipment_list.get_allocation()
        x, y = self.window.get_position()
        x += rect.x + rect.width / 2
        y += rect.y + rect.height / 2

        self.item_window.set_item(item_id)
        self.item_window.show(x, y)

    def __show_places(self):
        self.places_dialog.run()

    def __exit(self, widget=None):
        gtk.main_quit()


    # Class Methods -----------------------------------------------------------
    def new_persona(self, race, profession):
        self.persona_orig = None
        self.persona = data.Persona('')
        self.persona.race = race
        self.persona.profession = profession
        self.persona.specialization = None

        self.persona.skill_points = profession.skill_points
        self.persona.weapon_points = profession.weapon_points
        self.persona.combat_points = profession.combat_points

        self.race_entry.set_text(race.name)
        self.profession_entry.set_text(profession.name)

        self.attribute_wheel.set_modifiers(race.attribute_bonus)
        self.attribute_wheel.set_values(self.persona.attributes)

        self.refresh_personal()
        self.homeland_button.set_label('...')

        self.refresh_avatar_image(None)
        self.refresh_attributes()
        self.refresh_points()
        self.refresh_skills()
        self.refresh_equipment()
        self.refresh_money()
        self.refresh_ageheightweight(True)
        self.tmp_persona_names = []
        self.name_entry_completion_model_filter.refilter()

        self.show_skills_button.set_active(True)
        self.show_equip_button.set_active(True)

        if self.persona.profession.is_magic_user():
            self.refresh_spells()
            self.show_spells_button.set_active(True)


    def save_persona(self):
        if self.persona is None:
            return

        self.update_persona_data()
        self.store.save_persona(self.persona)

        if self.persona_orig is None:
            self.persona_orig = self.persona
            self.add_persona(self.persona)

    def load_persona(self, id):
        self.persona_orig = self.store.get_persona(id)
        self.persona = self.persona_orig

        self.attribute_wheel.set_modifiers(self.persona.race.attribute_bonus)
        self.attribute_wheel.set_values(self.persona.attributes)
        self.attribute_wheel.force_redraw()

        self.refresh_avatar_image(self.persona.avatar_file)

        self.refresh_personal()
        self.refresh_attributes()
        self.refresh_points()
        self.refresh_skills()
        self.refresh_equipment()
        self.refresh_money()
        self.refresh_ageheightweight(self.persona.race)

        if self.persona.god == -1:
            self.god_combo.set_active(-1)
        else:
            for row in self.god_combo_model:
                if row[gs.GOD_COL_ID] == self.persona.god:
                    self.god_combo.set_active_iter(row.iter)
                    break

        self.social_entry.set_text(self.persona.get_social_class())
        self.history_textbuffer.set_text(self.persona.history)
        self.goals_textbuffer.set_text(self.persona.goals)

        if self.persona.homeland is None:
            place = '...'
            place_id = -1
        else:
            place = self.persona.homeland.name
            place_id = self.persona.homeland.id
        self.homeland_button.set_label(place)
        self.places_dialog.set_place_id(place_id)

        self.persona_sizer.set_height(self.persona.height)
        self.persona_sizer.set_weight(self.persona.weight)
        self.persona_age.set_age(self.persona.age)

        self.eyes_entry.set_text(self.persona.eyes)
        self.hair_entry.set_text(self.persona.hair)
        self.skin_entry.set_text(self.persona.skin)
        self.appearence_textbuffer.set_text(self.persona.appearance)

        if self.persona.profession.is_magic_user():
            self.spells_list_filter.refilter()
            self.spells_list.expand_all()

        self.tmp_persona_names = []
        self.name_entry_completion_model_filter.refilter()

        self.show_skills_button.set_active(False)
        self.show_equip_button.set_active(False)

        if self.persona.profession.is_magic_user():
            self.refresh_spells()
            self.show_spells_button.set_active(False)


    def refresh_personal(self):
        if self.persona is None:
            return

        self.name_entry.set_text(self.persona.name)
        self.player_entry.set_text(self.persona.player)
        self.race_entry.set_text(self.persona.race.name)
        self.social_entry.set_text('Livre')
        self.god_combo.set_active(-1)

        self.profession_entry.set_text(self.persona.profession.name)
        self.prof_spec_label.set_markup('<b>%s:</b>' % \
            self.persona.profession.specialization_name)
        self.prof_spec_entry.set_text('')

        self.persona.level = core.get_level(self.persona.xp)
        self.xp_spin.set_value(self.persona.xp)
        self.xp_next_entry.set_text('%d' % core.get_xp_next(self.persona.level))
        self.level_entry.set_text('%d' % self.persona.level)

        self.appearence_textbuffer.set_text('')
        self.history_textbuffer.set_text('')
        self.goals_textbuffer.set_text('')
        self.places_dialog.reset()

    def refresh_attributes(self):
        if self.persona is None:
            return

        self.rf_label.set_text(str(self.persona.get_physical_resistance()))
        self.rm_label.set_text(str(self.persona.get_magical_resistance()))

        self.speed_label.set_text(str(self.persona.get_speed()))

        self.karma_label.set_text(str(self.persona.get_karma()))

        active_defense, passive_defense = self.persona.calc_defense()
        self.defense_label.set_text(str(active_defense))
        self.passive_defense_label.set_text(str(passive_defense))

        self.eh_label.set_text(str(core.calc_eh(self.persona)))
        self.ef_label.set_text(str(self.persona.get_max_ef()))
        self.absorption_label.set_text(str(self.persona.calc_absorption()))


    def refresh_points(self):
        if self.persona is None:
            return

        self.skill_pts_bar.set_property('max-value',
                                        self.persona.profession.skill_points)
        self.skill_pts_bar.set_property('value', self.persona.skill_points)

        self.weapon_pts_bar.set_property('max-value',
                                         self.persona.profession.weapon_points)
        self.weapon_pts_bar.set_property('value', self.persona.weapon_points)

        self.combat_pts_bar.set_property('max-value',
                                         self.persona.profession.combat_points)
        self.combat_pts_bar.set_property('value', self.persona.combat_points)

        if self.persona.profession.is_magic_user():
            magic = self.persona.calc_magic_points()
            self.magic_pts_bar.set_property('max-value', magic)
            self.magic_pts_bar.set_property('value', magic)
            self.hbox_magic.show()
        else:
            self.magic_pts_bar.set_property('max-value', 0)
            self.magic_pts_bar.set_property('value', 0)
            self.hbox_magic.hide()


    def refresh_avatar_image(self, image_file):
        if image_file is None:
            return

        image_path = join(cfg.APPDATAPATH, image_file)
        if image_path is None or not isfile(image_path):
            self.avatar_image.clear()
            self.avatar_image.set_from_stock(gtk.STOCK_ORIENTATION_PORTRAIT,
                                             gtk.ICON_SIZE_DND)
        else:
            pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(image_path, 90, 90)
            self.avatar_image.set_from_pixbuf(pixbuf)


    def refresh_ageheightweight(self, new_persona=False):
        if self.persona is None:
            return

        if new_persona:
            age = self.persona.race.calc_medium_age()
            self.persona_sizer.reset(self.persona.race)
        else:
            age = self.persona.age
            hw = (self.persona.height, self.persona.weight)
            self.persona_sizer.reset(self.persona.race, hw)

        self.persona_age.reset(self.persona.race.age, age)


    def refresh_skills(self, add_specs=True):
        skills = self.persona.skills.keys()

        def do_process_specializations(row):
            skill_id = row[gs.SKILLS_COL_ID]
            for spec, level in self.persona.skills_specs[skill_id]:
                total = level + self.persona.get_attribute_by_short_name(\
                                                row[gs.SKILLS_COL_BONUS])
                if add_specs:
                    cost = row[gs.SKILLS_COL_COST]
                    self.skills_list_model.append(row.iter,
                                                  [skill_id, spec, cost, level,
                                                   row[gs.SKILLS_COL_BONUS],
                                                   total, False, True, False,
                                                   gs.FG_COLOR, gs.COLOR_WHITE])
                else:
                    row[gs.SKILLS_COL_TOTAL] = total

        def do_process_row(row):
            if row[gs.SKILLS_COL_ID] in skills:
                level = self.persona.skills[row[gs.SKILLS_COL_ID]]
                if level == 0:
                    total = 0
                else:
                    total = level + self.persona.get_attribute_by_short_name(\
                                                 row[gs.SKILLS_COL_BONUS])

                row[gs.SKILLS_COL_LEVEL] = level
                row[gs.SKILLS_COL_TOTAL] = total
                row[gs.SKILLS_COL_UNKNOWN] = False

                if row[gs.SKILLS_COL_HAS_SPEC]:
                    do_process_specializations(row)
            else:
                row[gs.SKILLS_COL_LEVEL] = row[gs.SKILLS_COL_TOTAL] = 0
                row[gs.SKILLS_COL_UNKNOWN] = True

        def do_iterate_skills(skill_iter):
            try:
                while True:
                    row = skill_iter.next()
                    if row[gs.SKILLS_COL_IS_SKILL]:
                        do_process_row(row)
                    else:
                        do_iterate_skills(row.iterchildren())
            except StopIteration:
                pass

        do_iterate_skills(iter(self.skills_list_model))
        self.show_skills_button.set_active(False)
        self.show_skills_button.set_active(True)


    def refresh_spells(self):
        if not self.persona.profession.is_magic_user():
            return
        else:
            spells = self.persona.spells.keys()

        def do_process_row(row):
            known = row[gs.SPELLS_COL_ID] in spells
            row[gs.SPELLS_COL_UNKNOWN] = not known
            if known:
                row[gs.SPELLS_COL_LEVEL] = \
                        self.persona.spells[row[gs.SPELLS_COL_ID]]
            else:
                row[gs.SPELLS_COL_LEVEL] = 0

        def do_iterate_spells(spell_iter):
            try:
                while True:
                    row = spell_iter.next()
                    if row[gs.SPELLS_COL_IS_SPELL]:
                        do_process_row(row)
                    else:
                        do_iterate_spells(row.iterchildren())
            except StopIteration:
                pass

        do_iterate_spells(iter(self.spells_list_model))
        self.show_spells_button.set_active(False)
        self.show_spells_button.set_active(True)


    def refresh_equipment(self):
        equip = self.persona.equipment.keys()

        def do_process_row(row):
            hasit = row[gs.EQUIP_COL_ID] in equip
            row[gs.EQUIP_COL_NOTMINE] = not hasit

            if hasit:
                row[gs.EQUIP_COL_QTD] = \
                        self.persona.equipment[row[gs.EQUIP_COL_ID]]
            else:
                row[gs.EQUIP_COL_QTD] = 0

        def do_iterate_equipment(equip_iter):
            try:
                while True:
                    row = equip_iter.next()
                    if row[gs.EQUIP_COL_IS_ITEM]:
                        do_process_row(row)
                    else:
                        do_iterate_equipment(row.iterchildren())
            except StopIteration:
                pass

        self.combat_viewport.reset()

        do_iterate_equipment(iter(self.equipment_list_model))
        self.show_equip_button.set_active(False)
        self.show_equip_button.set_active(True)


    def refresh_money(self):
        self.copper_label.set_text(str(self.persona.copper_coins))
        self.silver_label.set_text(str(self.persona.silver_coins))
        self.gold_label.set_text(str(self.persona.gold_coins))


    def update_persona_data(self):
        self.persona.name = unicode(self.name_entry.get_text())
        self.persona.player = self.player_entry.get_text()

        self.persona.max_eh = self.persona.race.ef
        self.persona.eh = self.persona.profession.eh
        self.persona.ef = self.persona.get_max_ef()
        self.persona.absorption = self.persona.calc_absorption()

        self.persona.xp = self.xp_spin.get_value_as_int()

        self.persona.skill_points = self.skill_pts_bar.get_property('value')
        self.persona.weapon_points = self.weapon_pts_bar.get_property('value')
        self.persona.combat_points = self.combat_pts_bar.get_property('value')

        try:
            self.persona.magic_points = self.magic_pts_bar.get_property('value')
        except ValueError:
            self.persona.magic_points = 0

        self.persona.height = self.persona_sizer.get_height()
        self.persona.weight = self.persona_sizer.get_weight()
        self.persona.age = self.persona_age.get_age()

        self.persona.eyes = self.eyes_entry.get_text()
        self.persona.hair = self.hair_entry.get_text()
        self.persona.skin = self.skin_entry.get_text()
        first, last = self.appearence_textbuffer.get_bounds()
        self.persona.appearance = \
            self.appearence_textbuffer.get_text(first, last)

        self.persona.god = self.__get_selected_god_id()
        self.persona.social_class = \
            self.persona.get_social_class_id(self.social_entry.get_text())
        self.persona.homeland = self.places_dialog.get_place()
        first, last = self.history_textbuffer.get_bounds()
        self.persona.history = \
            self.history_textbuffer.get_text(first, last)
        first, last = self.goals_textbuffer.get_bounds()
        self.persona.goals = \
            self.goals_textbuffer.get_text(first, last)

        self.persona.copper_coins = int(self.copper_label.get_text())
        self.persona.silver_coins = int(self.silver_label.get_text())
        self.persona.gold_coins = int(self.gold_label.get_text())

        def _process_skill_specs(skills):
            specs = {}
            for skill in skills:
                specs[skill[gs.SKILLS_COL_ID]] = skill[gs.SKILLS_COL_LEVEL]

            return specs

        def _process_skills(skills):
            for skill in skills:
                if skill[gs.SKILLS_COL_HAS_SPEC]:
                    self.persona.skills[skill[gs.SKILLS_COL_ID]] = \
                        _process_skill_specs(skill.iterchildren())
                elif not skill[gs.SKILLS_COL_IS_SKILL]:
                    _process_skills(skill.iterchildren())
                else:
                    self.persona.skills[skill[gs.SKILLS_COL_ID]] = \
                        skill[gs.SKILLS_COL_LEVEL]

        _process_skills(self.skills_list_filter[0].iterchildren())

        def _process_spells(spells):
            for spell in spells:
                if not spell[gs.SPELLS_COL_IS_SPELL]:
                    _process_spells(spell.iterchildren())
                else:
                    self.persona.spells[spell[gs.SPELLS_COL_ID]] = \
                        spell[gs.SPELLS_COL_LEVEL]

        if self.persona.profession.is_magic_user():
            _process_spells(self.spells_list_filter[0].iterchildren())

        def _process_equipment(equipment):
            for item in equipment:
                if not item[gs.EQUIP_COL_IS_ITEM]:
                    _process_equipment(item.iterchildren())
                else:
                    self.persona.equipment[item[gs.EQUIP_COL_ID]] = \
                        item[gs.EQUIP_COL_QTD]

        _process_equipment(self.equipment_list_filter)


    def add_persona(self, persona):
        print self.persona_orig
        print self.persona
        tooltip = '<big><b>%s</b></big>\n%s, %s, nvl %d' % \
                  (persona.name, persona.race.name,
                   persona.profession.name, persona.level)

        self.persona_collection_model.append(\
            [persona.id, persona.name, persona.race.id, persona.level,
             tooltip, gs.PROFESSION_PIXMAPS[persona.race.id-1]])


    def __get_selected_god_id(self):
        iter = self.god_combo.get_active_iter()
        if iter is None:
            return -1
        return self.god_combo_model[iter][gs.GOD_COL_ID]


    def add_remove_skill(self, learn=True):
        path, column = self.skills_list.get_cursor()
        filter_iter = self.skills_list_filter.get_iter(path)
        iter = self.skills_list_filter.convert_iter_to_child_iter(filter_iter)

        if not self.skills_list_model[iter][gs.SKILLS_COL_IS_SKILL]:
            return

        if self.skills_list_model[iter][gs.SKILLS_COL_HAS_SPEC]:
            if not learn:
                return
            self.spec_skill_label.set_text('%s:' % \
                self.skills_list_model[iter][gs.SKILLS_COL_NAME_GROUP][:-4])
            self.spec_comboentry.set_active(-1)
            self.editing_skill_spec_id = \
                    self.skills_list_model[iter][gs.SKILLS_COL_ID]
            self.spec_combo_filter.refilter()
            self.spec_dialog.show()
            return

        cost = self.skills_list_model[iter][gs.SKILLS_COL_COST]
        level = self.skills_list_model[iter][gs.SKILLS_COL_LEVEL]
        bonus = self.skills_list_model[iter][gs.SKILLS_COL_BONUS]

        iter_parent_tmp = self.skills_list_model.iter_parent(iter)
        iter_parent = self.skills_list_model.iter_parent(iter_parent_tmp)
        if iter_parent is None:
            iter_parent = iter_parent_tmp

        parent_id = self.skills_list_model[iter_parent]\
                                          [gs.SKILLS_COL_ID]

        if parent_id == store.SKILL_POINTS:
            value_bar = self.skill_pts_bar
        elif parent_id == store.WEAPON_POINTS:
            value_bar = self.weapon_pts_bar
        else:
            value_bar = self.combat_pts_bar

        bonus_value = self.persona.get_attribute_by_short_name(bonus)
        points = value_bar.get_property('value')
        print 'b.points: %s' % points

        if learn:
            if points < cost:
                #self.statusbar.\
                #     push(0, 'Pontos insuficientes para adquirir habilidade.')
                return

            points -= cost
            level += 1

            if level > self.persona.level:
                #self.statusbar.\
                #     push(0, 'O nível de habilidade máxima não pode ' \
                #             'exceder o nível do personagem.')
                return

        else:
            if level < 1:
                return

            points += cost
            level -= 1

        #self.statusbar.pop(0)

        total = level + bonus_value

        self.skills_list_model[iter][gs.SKILLS_COL_LEVEL] = level
        self.skills_list_model[iter][gs.SKILLS_COL_TOTAL] = total
        self.skills_list_model[iter][gs.SKILLS_COL_UNKNOWN] = (level < 1)
        value_bar.set_property('value', points)
        print 'e.points: %s' % points


    def add_remove_spell(self, learn=True):
        path, column = self.spells_list.get_cursor()
        filter_iter = self.spells_list_filter.get_iter(path)
        iter = self.spells_list_filter.convert_iter_to_child_iter(filter_iter)

        if not self.spells_list_model[iter][gs.SPELLS_COL_IS_SPELL]:
            return

        cost = self.spells_list_model[iter][gs.SPELLS_COL_COST]
        level = self.spells_list_model[iter][gs.SPELLS_COL_LEVEL]

        iter_parent = self.spells_list_model.iter_parent(iter)
        parent_id = self.spells_list_model[iter_parent]\
                                          [gs.SPELLS_COL_ID]

        points = self.magic_pts_bar.get_property('value')

        if learn:
            if points < cost:
                #self.statusbar.\
                #     push(0, 'Pontos insuficientes para adquirir magia.')
                return

            points -= cost
            level += 1

            if level > self.persona.level:
                #self.statusbar.\
                #     push(0, 'O nível máximo na magia não pode ' \
                #             'exceder o nível do personagem.')
                return

        else:
            if level < 1:
                return

            points += cost
            level -= 1

        #self.statusbar.pop(0)

        self.spells_list_model[iter][gs.SPELLS_COL_UNKNOWN] = level < 1

        self.spells_list_model[iter][gs.SPELLS_COL_LEVEL] = level
        self.magic_pts_bar.set_property('value', points)


    def buy_sell_item(self, buy=True):
        path, column = self.equipment_list.get_cursor()
        filter_iter = self.equipment_list_filter.get_iter(path)
        iter = self.equipment_list_filter.convert_iter_to_child_iter(filter_iter)

        if not self.equipment_list_model[iter][gs.EQUIP_COL_IS_ITEM]:
            return

        price = self.equipment_list_model[iter][gs.EQUIP_COL_PRICE]
        qtd = self.equipment_list_model[iter][gs.EQUIP_COL_QTD]

        money = self.persona.get_money()

        if buy:
            deal, change = core.buy(price, self.persona.get_coins())
            if deal:
                self.persona.set_coins(change)
                qtd += 1

        elif qtd > 0:
            qtd -= 1
            self.persona.add_money(price)

            item_id = self.equipment_list_model[iter][gs.EQUIP_COL_ID]
            item = self.store.get_equipment_item(item_id)

            if self.combat_viewport.unequip_item(item):
                self.persona.unequip_item(item)

        self.refresh_money()

        self.equipment_list_model[iter][gs.EQUIP_COL_NOTMINE] = qtd < 1
        self.equipment_list_model[iter][gs.EQUIP_COL_QTD] = qtd


    # Metodos de visibilidade
    def skills_visible(self, model, iter, user_data):
        if self.persona is None:
            return True

        show_available = self.show_skills_button.get_active()

        if model[iter][gs.SKILLS_COL_IS_SKILL]:
            return show_available or model[iter][gs.SKILLS_COL_LEVEL] > 0

        if model[iter][gs.SKILLS_COL_ID] not in (10, 11, 12, 13): #FIXME: Gambiarra!
            return True

        spec = self.persona.specialization
        if spec is None:
            return False
        else:
            return model[iter][gs.SKILLS_COL_ID] == spec.technique_group

    def skill_spec_suggestion_visible(self, model, iter, user_data):
        return model[iter][gs.SPECSUGGEST_COL_SKILL_ID] == \
               self.editing_skill_spec_id

    def spells_visible(self, model, iter, user_data):
        if self.persona is None or \
           not self.persona.profession.is_magic_user():
            return False

        show_available = self.show_spells_button.get_active()

        if model[iter][gs.SPELLS_COL_IS_SPELL]:
            return show_available or model[iter][gs.SPELLS_COL_LEVEL] > 0

        group_id = model[iter][gs.SPELLS_COL_GROUP_ID]

        if group_id == self.persona.profession.spell_group:
            return True

        if self.persona.specialization is None:
            return False

        return group_id == self.persona.specialization.spell_group

    def equipment_visible(self, model, iter, user_data):
        show_available = self.show_equip_button.get_active()
        if show_available:
            return True
        else:
            return not model[iter][gs.EQUIP_COL_IS_ITEM] or \
                   model[iter][gs.EQUIP_COL_QTD] > 0

    def personas_names_visible(self, model, iter, user_data):
        if self.persona is None:
            return True

        if self.persona.race.id != model[iter][gs.PERSONA_COL_RACE_ID]:
            return False

        name = model[iter][gs.PERSONA_COL_NAME]
        if name in self.tmp_persona_names:
            return False
        else:
            self.tmp_persona_names.append(name)
            return True

    def run(self):
        gtk.main()


def main():
    app = AppWindow()
    app.run()

if __name__ == '__main__':
    main()
